/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package biz.c24.io.spring.http; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.Set; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.util.Assert; import biz.c24.io.api.data.ComplexDataObject; import biz.c24.io.api.presentation.Sink; import biz.c24.io.api.presentation.Source; import biz.c24.io.api.presentation.TextualSink; import biz.c24.io.api.presentation.TextualSource; import biz.c24.io.api.presentation.XMLSink; import biz.c24.io.api.presentation.XMLSource; import biz.c24.io.spring.core.C24Model; import biz.c24.io.spring.core.DataFormat; import biz.c24.io.spring.core.DataFormats; import biz.c24.io.spring.util.C24Utils; /** * {@link HttpMessageConverter} being able to convert objects of a {@link C24Model} into the specified data format. * * @author Oliver Gierke */ public class C24HttpMessageConverter implements HttpMessageConverter<ComplexDataObject> { private final C24Model model; private final DataFormats dataFormat; /** * Creates a new {@link C24HttpMessageConverter} for the given {@link C24Model} and {@link DataFormat}. * * @param model * @param dataFormat */ public C24HttpMessageConverter(C24Model model, Set<DataFormat> dataFormat) { Assert.notNull(model); Assert.notNull(dataFormat); this.model = model; this.dataFormat = new DataFormats(dataFormat); } /* (non-Javadoc) * @see org.springframework.http.converter.HttpMessageConverter#canRead(java.lang.Class, org.springframework.http.MediaType) */ public boolean canRead(Class<?> clazz, MediaType mediaType) { return ComplexDataObject.class.isAssignableFrom(clazz) && dataFormat.supports(mediaType); } /* (non-Javadoc) * @see org.springframework.http.converter.HttpMessageConverter#canWrite(java.lang.Class, org.springframework.http.MediaType) */ public boolean canWrite(Class<?> clazz, MediaType mediaType) { return canRead(clazz, mediaType); } /* (non-Javadoc) * @see org.springframework.http.converter.HttpMessageConverter#getSupportedMediaTypes() */ public List<MediaType> getSupportedMediaTypes() { return dataFormat.getSupportedMediaTypes(); } /* (non-Javadoc) * @see org.springframework.http.converter.HttpMessageConverter#read(java.lang.Class, org.springframework.http.HttpInputMessage) */ public ComplexDataObject read(Class<? extends ComplexDataObject> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { HttpHeaders headers = inputMessage.getHeaders(); MediaType contentType = headers.getContentType(); Source source = getSourceFor(inputMessage.getBody(), contentType); ComplexDataObject result = source.readObject(model.getElementFor(clazz)); return C24Utils.potentiallyUnwrapDocumentRoot(result); } /* * (non-Javadoc) * @see org.springframework.http.converter.HttpMessageConverter#write(java.lang.Object, org.springframework.http.MediaType, org.springframework.http.HttpOutputMessage) */ public void write(ComplexDataObject t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { Sink sink = getSinkFor(outputMessage.getBody(), contentType); sink.writeObject(t); } private Source getSourceFor(InputStream stream, MediaType mediaType) { switch (dataFormat.getTypeFor(mediaType)) { case XML: return new XMLSource(stream); case TEXT: return new TextualSource(stream); default: throw new IllegalStateException("Unsupported data format!"); } } private Sink getSinkFor(OutputStream stream, MediaType mediaType) { switch (dataFormat.getTypeFor(mediaType)) { case XML: return new XMLSink(stream); case TEXT: return new TextualSink(stream); default: throw new IllegalStateException("Unsupported data format!"); } } }